package calendar;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.ArrayList;
import java.util.Date;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.Popup;
import javax.swing.PopupFactory;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;

/* this class is main client panel for user interface */
public class ClientPanel extends CalendarPanel {

  private static final long serialVersionUID = 4934757L;

  ConnectPanel connectPanel;
  CreatePanel createPanel;
  StatusPanel statusPanel;
  CreateEventPanel createEventPanel;
  EventPanel eventPanel;
  UserListPanel userListPanel;
  EventListPanel eventListPanel;
  AlertPanel alertPanel;
  JPanel buttonPanel;
  JButton closeButton;
  JButton clearButton;

  JScrollPane userListPanelScroller;
  JScrollPane eventListPanelScroller;

  Dimension userListPanelSize;
  Dimension eventListPanelSize;

  CalendarObjInt currentCal = null;

  HashMap panels;

  final static Dimension panelSize = new Dimension( 700, 1000 );

  public ClientPanel()
  {
    connectPanel = new ConnectPanel();
    createPanel = new CreatePanel();
    statusPanel = new StatusPanel();
    createEventPanel = new CreateEventPanel();
    eventPanel = new EventPanel();
    userListPanel = new UserListPanel();
    eventListPanel = new EventListPanel( createEventPanel, statusPanel );
    buttonPanel = new JPanel();
    alertPanel = new AlertPanel();
    closeButton = new JButton( "Close" );
    clearButton = new JButton( "Clear Log" );
  
    userListPanelScroller = new JScrollPane( userListPanel );
    eventListPanelScroller = new JScrollPane( eventListPanel );
    panels = new HashMap();

    Border blackBorder = BorderFactory.createLineBorder( Color.black );

    closeButton.setFont( new Font( "Dialog", Font.BOLD, 12 ) );
    clearButton.setFont( new Font( "Dialog", Font.BOLD, 12 ) );
    closeButton.addActionListener( this );
    clearButton.addActionListener( this );

    Dimension statusPanelSize = new Dimension( 690, 20 );

    Dimension connectPanelSize = new Dimension( 370, 30 );
    Dimension createEventPanelSize = new Dimension( 370, 200 );
    Dimension eventPanelSize = new Dimension( 370, 200 );

    Dimension createPanelSize = new Dimension( 350, 30 );
    userListPanelSize = new Dimension( 330, 1000 );
    Dimension userListPanelScrollerSize = new Dimension( 350, 200 );
    eventListPanelSize = new Dimension( 330, 1000 );
    Dimension eventListPanelScrollerSize = new Dimension( 350, 200 );
    
    Dimension alertPanelSize = new Dimension( 690, 200 );
    Dimension buttonPanelSize = new Dimension( 690, 40 );

    panels.put( connectPanel, connectPanelSize );
    panels.put( createPanel, createPanelSize );
    panels.put( statusPanel, statusPanelSize );
    panels.put( createEventPanel, createEventPanelSize );
    panels.put( eventPanel, eventPanelSize );
    panels.put( userListPanel, userListPanelSize );
    panels.put( eventListPanel, eventListPanelSize );
    panels.put( alertPanel, alertPanelSize );
    panels.put( buttonPanel, buttonPanelSize );

    Set set = panels.entrySet();
    Iterator iterator = set.iterator();
    while ( iterator.hasNext() )
    {
      Map.Entry entry = (Map.Entry)iterator.next();
      ((JPanel)entry.getKey()).setMaximumSize( (Dimension)entry.getValue() );
      ((JPanel)entry.getKey()).setMinimumSize( (Dimension)entry.getValue() );
      ((JPanel)entry.getKey()).setPreferredSize( (Dimension)entry.getValue() );
      ((JPanel)entry.getKey()).setBorder( blackBorder );
    }

    userListPanelScroller.setMaximumSize( userListPanelScrollerSize );
    userListPanelScroller.setMinimumSize( userListPanelScrollerSize );
    userListPanelScroller.setPreferredSize( userListPanelScrollerSize );
    eventListPanelScroller.setMaximumSize( eventListPanelScrollerSize );
    eventListPanelScroller.setMinimumSize( eventListPanelScrollerSize );
    eventListPanelScroller.setPreferredSize( eventListPanelScrollerSize );

    closeButton.setAlignmentX( Component.CENTER_ALIGNMENT );
    clearButton.setAlignmentY( Component.CENTER_ALIGNMENT );
    buttonPanel.setLayout( new BoxLayout( buttonPanel, BoxLayout.X_AXIS ));
    buttonPanel.add( Box.createHorizontalStrut( 220 ) );
    buttonPanel.add( closeButton );
    buttonPanel.add( Box.createHorizontalStrut( 40 ) );
    buttonPanel.add( clearButton );
    statusPanel.setBackground( Color.RED );

    setLayout( new GridBagLayout() );
    GridBagConstraints c = new GridBagConstraints();

    c.fill = GridBagConstraints.HORIZONTAL;

    c.gridx = 0; c.gridy = 0; c.gridwidth = 1;
    add( connectPanel, c );
    c.gridx = 1; c.gridy = 0; c.gridwidth = 1;
    add( createPanel, c );
    c.gridx = 0; c.gridy = 1; c.gridwidth = 2;
    add( statusPanel, c );
    c.gridx = 0; c.gridy = 2; c.gridwidth = 1;
    add( createEventPanel, c );
    c.gridx = 1; c.gridy = 2; c.gridwidth = 1;
    add( userListPanelScroller, c );
    c.gridx = 0; c.gridy = 3; c.gridwidth = 1;
    add( eventPanel, c );
    c.gridx = 1; c.gridy = 3; c.gridwidth = 1;
    add( eventListPanelScroller, c );
    c.gridx = 0; c.gridy = 4; c.gridwidth = 2;
    add( alertPanel, c );
    c.gridx = 0; c.gridy = 5; c.gridwidth = 2;
    add( buttonPanel, c );

    setSize( panelSize );
  }

  public void setUsers( ArrayList users )
  {
    userListPanel.setUsers( users );
  }
  
  public ArrayList getUsers()
  {
    return userListPanel.getUsers();
  }

  public String getUserName()
  {
    return createPanel.getUserName();
  }

  /* add an alert to the alert log */
  public synchronized void addAlert( String alert )
  {
    Calendar cal = Calendar.getInstance();
    long time = cal.getTimeInMillis();
    alertPanel.addAlert( (double)time, alert );
  }

  /* popup a message when an event is starting */
  public synchronized void showPopup( String alert )
  {
    TitledBorder title = BorderFactory.createTitledBorder("Appointment Alert");
    JPanel panel = new JPanel();
    panel.setBorder( title );
    JLabel label = new JLabel( alert );
    panel.add( label );
    PopupFactory factory = PopupFactory.getSharedInstance();
    Popup popup = factory.getPopup( this, panel, 400, 400 );
    popup.show();
    try
    {
      Thread.sleep(5000);
    }
    catch(InterruptedException ex)
    {
      System.out.println( "ClientPanel: showPopup -> " + ex );
    }
    popup.hide();
  }

  public synchronized int getUserId()
  {
    return connectPanel.getUserId();
  }

  /* provide the remote calendar object to this client user interface */
  public void setCalendar( CalendarObjInt calendar )
  {
    currentCal = calendar;
    eventListPanel.setCalendar( calendar);
  }

  public CalendarObjInt getCalendar()
  {
    return currentCal;
  }

  public void setConnectName( String name )
  {
    statusPanel.setConnectName( name );
    statusPanel.setBackground( Color.GREEN );
  }

  public void setDisconnected()
  {
    statusPanel.setDisconnected();
    statusPanel.setBackground( Color.RED );
  }

  public int getNewEventType()
  {
    return createEventPanel.getType();
  }

  public Date getNewEventStartDate()
  {
    return createEventPanel.getStartDate();
  }

  public Date getNewEventEndDate()
  {
    return createEventPanel.getEndDate();
  }

  public String getNewEventDesc()
  {
    return createEventPanel.getDesc();
  }

  public ArrayList getSelectedUsers()
  {
    return userListPanel.getSelectedUsers();
  }

  public void clearSelectedUsers()
  {
    userListPanel.clearSelectedUsers();
  }

  public void setUserChecked( User user )
  {
    userListPanel.setUserChecked( user );
  }

  public Event getSelectedEvent()
  {
    return eventListPanel.getSelectedEvent();
  }

  public void listUserEvents( ArrayList users )
  {
    eventListPanel.listUserEvents( users );
  }

  public void showEvent( Event event, int currentUserId )
  {
    eventPanel.showEvent( event, currentUserId );
    createEventPanel.loadEvent( event );
  }

  public void resetEventList()
  {
    eventListPanel.resetList();
  }

  public void setFocusConnect()
  {
    connectPanel.setFocusConnect();
  }

  public void setFocusCreate()
  {
    createPanel.setFocusCreate();
  }

  public void clearConnectText()
  {
    connectPanel.clearText();
  }

  public void clearCreateText()
  {
    createPanel.clearText();
  }

  public void clearEventPanel()
  {
    eventPanel.removeAll();
    eventPanel.addTitle();
    eventPanel.updateUI();
    setCreateEventPanelButtonsEnabled();
  }

  public void resetCreateEventPanel()
  {
    createEventPanel.reset();
  }

  public synchronized void resetUserListPanel( ArrayList users )
  {
    userListPanel.setUsers( users );
  }

  public void setCreateEventPanelButtonsEnabled()
  {
    createEventPanel.setButtonsEnabled();
    createEventPanel.setEditButtonDisabled();
  }

  public boolean areCreateEventPanelButtonsDisabled()
  {
    return createEventPanel.areButtonsDisabled();
  }
  
  public void actionPerformed(ActionEvent e) {
    int eventId = -1;
    if ( e.getSource() == closeButton )
    {
      eventId = CalEvent.CLOSE;
      CalEvent calEvent = new CalEvent( this, eventId );
      fireCalEvent( calEvent );
    }
    else if ( e.getSource() == clearButton )
    {
      alertPanel.clearLog();
    }
    else return;
  }

  public void addCalEventListener ( CalEventListener listener )
  {
    listenerList.add ( CalEventListener.class, listener ) ;
    connectPanel.addCalEventListener ( listener ) ;
    createPanel.addCalEventListener ( listener ) ;
    createEventPanel.addCalEventListener ( listener ) ;
    eventPanel.addCalEventListener ( listener ) ;
    userListPanel.addCalEventListener ( listener ) ;
    eventListPanel.addCalEventListener ( listener ) ;
    statusPanel.addCalEventListener( listener );
  }

  public void removeCalEventListener ( CalEventListener listener )
  {
    listenerList.remove ( CalEventListener.class, listener ) ;
    connectPanel.removeCalEventListener ( listener ) ;
    createPanel.removeCalEventListener ( listener ) ;
    createEventPanel.removeCalEventListener ( listener ) ;
    eventPanel.removeCalEventListener ( listener ) ;
    userListPanel.removeCalEventListener ( listener ) ;
    eventListPanel.removeCalEventListener ( listener ) ;
    statusPanel.removeCalEventListener( listener );
  }
}
